package util;

import java.io.FileInputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

//�������ӵĹ�����
public class DBUtil {
	private static Properties p = new Properties();

	static {

		try {
			// src/jdbc.propertes
			p.load(DBUtil.class.getClassLoader().getResourceAsStream(
					"jdbc.properties"));
			// Class.forName("com.mysql.jdbc.Driver");
			Class.forName(p.getProperty("driver"));

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private DBUtil() {
	}

	final static String url = p.getProperty("url");// "jdbc:mysql://localhost:3306/xingcheng";

	// public static DataSource ds = getDs();

	// public static Connection getConnection() {
	// Connection con = null;
	// try {
	// con = ds.getConnection();
	// System.out.println("hashCode:" + con.hashCode());
	// System.out.println("con class:" + con.getClass().getName());
	// return con;
	// } catch (SQLException e) {
	// e.printStackTrace();
	// throw new RuntimeException(e);
	// }
	// // return con;
	// }

	public static Connection getConnection() {
		Connection con = null;
		try {
			con = DriverManager.getConnection(url, p.getProperty("user"),
					p.getProperty("password"));
			return con;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		// return con;
	}

	public static void close(Connection con, Statement st, ResultSet rs) {
		close(rs);
		close(st);
		close(con);
	}

	public static void close(Connection con) {
		if (con != null)
			try {
				con.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	public static void close(Statement st) {
		if (st != null)
			try {
				st.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	public static void close(ResultSet rs) {
		if (rs != null)
			try {
				rs.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	// // /
	// public static int executeUpdate(String sql, Object... args) {
	// Connection con = getConnection();
	// PreparedStatement ps = null;
	// try {
	// ps = con.prepareStatement(sql);
	// for (int i = 0; i < args.length; i++) {
	// // args[i].getClass()==java.util.Date.class
	// // if(args[i] instanceof java.util.Date)
	// // {
	// // //��������
	// //
	// // }
	// // blob
	// ps.setObject(i + 1, args[i]);
	// }
	// return ps.executeUpdate();
	// } catch (SQLException e) {
	// e.printStackTrace();
	// throw new RuntimeException(e);
	// } finally {
	// close(con, ps, null);
	// }
	//
	// }
	//
	// // �ٸ�����
	// public static java.util.List<Map<String, Object>> query(String sql,
	// Object... args) {
	// java.util.List<Map<String, Object>> datas = new
	// java.util.ArrayList<Map<String, Object>>();
	// Connection con = getConnection();
	// PreparedStatement ps = null;
	// ResultSet rs = null;
	// try {
	// ps = con.prepareStatement(sql);
	// for (int i = 0; i < args.length; i++) {
	//
	// ps.setObject(i + 1, args[i]);
	// }
	// rs = ps.executeQuery();
	// ResultSetMetaData rm = rs.getMetaData();
	// while (rs.next()) {
	// Map<String, Object> entity = new HashMap<String, Object>();
	// // ��map�������е�ʵ��
	// for (int i = 1; i <= rm.getColumnCount(); i++) {
	// entity.put(rm.getColumnLabel(i),
	// rs.getObject(rm.getColumnLabel(i)));
	// }
	// datas.add(entity);
	// }
	// } catch (SQLException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// } finally {
	// close(con, ps, rs);
	// }
	//
	// return datas;
	// }
	//
	public static <T extends Serializable> java.util.List<T> query2(String sql,
			Class<T> t, Object... args) {
		// t.getClass().getName();
		List<T> datas = new ArrayList<T>();

		Connection con = DBUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = con.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}

			rs = ps.executeQuery();
			ResultSetMetaData rm = rs.getMetaData();
			while (rs.next()) {
				T obj = (T) t.newInstance();// �޲ι��췽��

				for (int i = 1; i <= rm.getColumnCount(); i++) {
					String field = rm.getColumnLabel(i);// �������
					Field f = t.getDeclaredField(field);// ��������Ϊ�������������
					f.setAccessible(true);// ȡ��private������
					f.set(obj, rs.getObject(field));// ����obj���������
				}
				datas.add(obj);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DBUtil.close(con, ps, rs);
		}
		return datas;
	}

	public static List query3(String id) {
		List datas = new ArrayList();
		// 1:解析xml,拿到sql和对应的类型
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(DBUtil.class.getClassLoader()
					.getResourceAsStream("smb.xml"));
			// xpath查询
			Element ele = (Element) doc.selectSingleNode("/sql/select[@id=\""
					+ id + "\"]");
			if (ele == null)
				return datas;
			String className = ele.attributeValue("type");
			String sql = ele.getText();
			// System.out.println(className + "," + sql);
			Connection con = DBUtil.getConnection();
			PreparedStatement ps = con.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();// 不考虑有参数的情况
			ResultSetMetaData rm = rs.getMetaData();
			Class oc = Class.forName(className);
			while (rs.next()) {
				Object obj = oc.newInstance();
				for (int i = 1; i <= rm.getColumnCount(); i++) {
					String field = rm.getColumnLabel(i);
					Field f = oc.getDeclaredField(field);// ��������Ϊ�������������
					f.setAccessible(true);// ȡ��private������
					f.set(obj, rs.getObject(field));
				}
				datas.add(obj);
			}
			DBUtil.close(con, ps, rs);// finally
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}

		return datas;
	}

	public static void main(String[] args) {
		List list = query3("findAll");
		// System.out.println(list);
		for (Object o : list) {
			System.out.println(o);
		}
	}
}
